﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Javavaj.iHunter;
using Javavaj.iHunter.Core;
namespace Javavaj.iHunter.UI
{
 
    public partial class PluginManagementForm : Form
    {
        private bool listInitializing = true;
        public PluginManagementForm()
        {
            InitializeComponent();
            listInitializing = true;
            this.listPlugins.Groups.Clear();
            this.listPlugins.Groups.Add("Unknown", labelGruopUnkownText.Text);
            this.listPlugins.Groups.Add("Channel", labelGroupChannelText.Text);
            this.listPlugins.Groups.Add("Viewer", labelGroupViewerText.Text);
            this.listPlugins.Groups.Add("Filter", labelGroupFilterText.Text);

            this.Shown += delegate
            {
                listInitializing = false;
            };

        }
        
        public IList<PluginInformation> pluginList;
        public IList<PluginInformation> PluginList
        {
            get
            {
                return pluginList;
            }
            set
            {
                pluginList = value;
                LoadPluginList();
            }
        }
        public event PluginInstallRequestedEventHandler PluginInstallRequested;
        public event PluginRemoveRequestedEventHandler PluginRemoveRequested;
        public event PluginConfigRequestedEventHandler PluginConfigRequested;
        public event PluginInfoChangedEventHandler PluginInfoChanged;


        public DialogResult ShowManagementDialog()
        {
            listInitializing = true;
            return ShowDialog();
        }
        private void LoadPluginList()
        {
            listInitializing = true;
            try
            {
                this.listPlugins.Items.Clear();
                if (pluginList == null)
                    return;
                foreach (PluginInformation info in PluginList)
                {
                    ListViewItem item = new ListViewItem(info.Name);
                    
                    item.SubItems.Add(info.Version);
                    item.Tag = info;
                    item.Checked = info.Enabled;
                    switch (info.PluginType)
                    {
                        case PluginType.ChannelPlugin:
                            item.Group = listPlugins.Groups["Channel"];
                            break;
                        case PluginType.ViewerPlugin:
                            item.Group = listPlugins.Groups["Viewer"];
                            break;
                        case PluginType.FilterPlugin:
                            item.Group = listPlugins.Groups["Filter"];
                            break;
                        default:
                            item.Group = listPlugins.Groups["Unknown"];
                            break;
                    }
                    listPlugins.Items.Add(item);
                }
            }
            catch
            {
            }
            finally
            {
                listInitializing = false;
            }
        }

        private void buttonInstall_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() != DialogResult.OK)
                return;
            string filename = openFileDialog.FileName;

            OnInstallRequested(filename);
        }

        private void OnInstallRequested(string filename)
        {
            if (listInitializing)
                return;
            if (PluginInstallRequested != null)
            {
                PluginInstallRequested.Invoke(this, new PluginInstallRequestedEventArgs(filename));
                LoadPluginList();
            }
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            if (this.listPlugins.SelectedItems.Count == 0)
                return;

            ListViewItem item = listPlugins.SelectedItems[0];
            PluginInformation info = (PluginInformation)item.Tag;
            if (info.Global)
            {
                MessageBox.Show(this, labelGlobalCannotDeleteText.Text, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            OnRemoveRequested(info);

        }



        private void buttonConfig_Click(object sender, EventArgs e)
        {
            if (this.listPlugins.SelectedItems.Count == 0)
                return;
            OnConfigRequested();
        }


        private void buttonOk_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void listPlugins_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (listInitializing)
                return;
            if (e.Item == null)
                return;
            PluginInformation info = (PluginInformation)e.Item.Tag;
            if (info.Enabled == e.Item.Checked)
                return;

            info.Enabled = e.Item.Checked;
            OnInfoChanged(info);
        }
        private void OnConfigRequested()
        {
            if (listInitializing)
                return;
            if (PluginConfigRequested != null)
            {
                PluginConfigRequested.Invoke(this, new PluginConfigRequestedEventArgs((PluginInformation)listPlugins.SelectedItems[0].Tag));
                LoadPluginList();
            }
        }
        private void OnRemoveRequested(PluginInformation info)
        {
            if (listInitializing)
                return;
            if (PluginRemoveRequested != null)
            {
                PluginRemoveRequested.Invoke(this, new PluginRemoveRequestedEventArgs(info));
                LoadPluginList();
            }
            return;
        }
        private void OnInfoChanged(PluginInformation info)
        {
            if (listInitializing)
                return;

            if (PluginInfoChanged != null)
            {
                PluginInfoChanged.Invoke(this, new PluginInfoChangedEventArgs(info));
                LoadPluginList();
            }
            return;
        }
       
    }

    public class PluginInstallRequestedEventArgs : EventArgs
    {
        private string assemblyPath;

        public string AssemblyPath
        {
            get { return assemblyPath; }

        }

        public PluginInstallRequestedEventArgs(string assemblyPath)
            : base()
        {
            this.assemblyPath = assemblyPath;
        }



    }
    public delegate void PluginInstallRequestedEventHandler(object sender, PluginInstallRequestedEventArgs e);
    
    public class PluginRemoveRequestedEventArgs : EventArgs
    {
        private PluginInformation info;

        public PluginInformation Information
        {
            get { return info; }

        }

        public PluginRemoveRequestedEventArgs(PluginInformation info)
            : base()
        {
            this.info = info;
        }

    }
    public delegate void PluginRemoveRequestedEventHandler(object sender, PluginRemoveRequestedEventArgs e);
    
    public class PluginConfigRequestedEventArgs : EventArgs
    {
        private PluginInformation info;

        public PluginInformation Information
        {
            get { return info; }

        }

        public PluginConfigRequestedEventArgs(PluginInformation info)
            : base()
        {
            this.info = info;
        }

    }
    public delegate void PluginConfigRequestedEventHandler(object sender, PluginConfigRequestedEventArgs e);
    
    public class PluginInfoChangedEventArgs : EventArgs
    {
        private PluginInformation info;

        public PluginInformation Information
        {
            get { return info; }

        }

        public PluginInfoChangedEventArgs(PluginInformation info)
            : base()
        {
            this.info = info;
        }

    }
    public delegate void PluginInfoChangedEventHandler(object sender, PluginInfoChangedEventArgs e);

}
